package com.hp.bon.sgw.wh.channel.invoices;

import org.simpleframework.http.Request;
import org.simpleframework.http.Response;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;
import com.hp.bon.sgw.wh.channel.common.BizConsts;
import com.hp.bon.sgw.wh.channel.common.BizParam;
import com.hp.bon.sgw.wh.channel.common.BizResult;
import com.hp.bon.sgw.wh.service.TMallResponseService;
import com.hp.bon.sgw.wh.service.UserResourceConfigService;
import com.hp.bon.sgw.wh.utils.LogUtil;

public class InvoiceBizProcedure {

	private static final Logger _log = LoggerFactory.getLogger(InvoiceBizProcedure.class);

	private RequestParser requestParser;
	private InvoiceBizRouter invoiceBizRouter;
	private Responsor responsor;
	private InvoiceConfigLoader invoiceConfigLoader;
	
	private UserResourceConfigService urcService;

	private static InvoiceBizProcedure invoiceBizProcedure;

	public static InvoiceBizProcedure instance() {
		if (null == invoiceBizProcedure) {
			invoiceBizProcedure = new InvoiceBizProcedure();
			invoiceBizProcedure.init();
		}
		return invoiceBizProcedure;
	}

	private void init() {
		//
		requestParser = new RequestParser();
		// 初始化发票接口路由业务类
		invoiceBizRouter = new InvoiceBizRouter();
		invoiceBizRouter.init();
		//
		responsor = new Responsor();
		//
		invoiceConfigLoader = new InvoiceConfigLoader();
	}

	public synchronized void setUserResourceConfigService(UserResourceConfigService urcService) {
		if (null == this.urcService) {
			this.urcService = urcService;
		}
	}
	
	public void setTMallResponseService(TMallResponseService tmallResponseService) {
		responsor.setTMallResponseService(tmallResponseService);
	}

	public String doProcedure(Request request, Response response, long startTime) {

		// 步骤1： 判断zw_falg 0走老流程,1走新流程
		int zw_flag = UserResourceConfigService.getIntValue("zw_flag", 0);
		if (zw_flag == 0) {
			// 走现在的流程和调用 (老流程)
			return BizConsts.TYPE_ORIG_FLOW;
		}
		// 步骤2：解析请求参数中的latnId
		BizParam bizParam = requestParser.doParser(request);

		// 把Request开始处理的时间加入BizParam中
		bizParam.setParam(BizConsts.KEY_RQUEST_START_TIME, Long.valueOf(startTime));
		_log.debug("bizParam={}", JSON.toJSONString(bizParam));

		// 步骤3：判断是否为：非修改发票信息接口 或 修改发票信息接口
		String latnId = bizParam.getParamString(BizConsts.KEY_INVOICE_LANID);
		String flagInvoiceModify = bizParam.getParamString(BizConsts.FLAG_INVOICE_MODIFY);
		_log.info("config: flagInvoiceModify={},latnId={}, ", flagInvoiceModify, latnId);
		if ("0".equals(flagInvoiceModify)) {
			// 步骤2.1：非修改发票信息接口对应：0
			// (非修改发票信息接口)取入参lanId，截取前五位判断; 如果不在(zw_jt_latn)中，则还是走现有接口和流程；
			String zwJtLatn = UserResourceConfigService.getValue("zw_jt_latn", "999");
			_log.info("zw_jt_latn={}", zwJtLatn);
			if (!("888".equals(zwJtLatn))) {
				_log.debug("zwJtLatn.indexOf(latnId.substring(0,5)) < 0 ? {}",zwJtLatn.indexOf(latnId.substring(0,5)) < 0);
				if (zwJtLatn.indexOf(latnId.substring(0,5)) < 0) {
					// 走现在的流程和调用 (老流程)
					return BizConsts.TYPE_ORIG_FLOW;
				}
			}
		} else if ("1".equals(flagInvoiceModify)) {
			// 步骤2.2：修改发票信息接口: 1
			// (修改发票信息接口)取入参lanId，截取前五位判断; 如果不在(zw_latn)中，则还是现有接口和流程；
			String zwLatn = UserResourceConfigService.getValue("zw_latn", "");
			_log.info("zwLatn={}", zwLatn);
			String processor = request.getValue("X-CTG-Region-ID");
			if (processor == null) {
				processor = request.getValue("X-CTG-Lan-ID");
			}
			if (!("888".equals(zwLatn))) {
				_log.debug("zwLatn.indexOf(processor) < 0 ? {}",zwLatn.indexOf(processor.substring(0,5)) < 0);
				_log.debug("processor.substring(0,5) ? {}",processor.substring(0,5));
				if (zwLatn.indexOf(processor.substring(0,5)) < 0) {
					// 走现在的流程和调用 (老流程)
					return BizConsts.TYPE_ORIG_FLOW;
				}
			}
		} else {
			// 步骤2.3：内部参数或配置错误
			_log.error("config: flagInvoiceModify,latnId={}, ", JSON.toJSONString(bizParam));
			// errorAck(body, "", "", STATUS_FAIL, "9999", "do business fail");
			responsor.doExceptionResponse(response, "FAILED", "9999", "zw latn config fail");
			return BizConsts.TYPE_ERROR_FLOW;
		}

		// 步骤4：把配置信息加入BizParam中
		bizParam = invoiceConfigLoader.doLoader(bizParam);

		// 步骤5：路由到请求对应的处理类：slot
		String requestPath = bizParam.getParamString(BizConsts.KEY_REQUEST_PATH);;
		String requestMethod = bizParam.getParamString(BizConsts.KEY_REQUEST_METHOD);
		BizSlot bizSlot = invoiceBizRouter.routeBizSlot(requestPath, requestMethod);
		if (null == bizSlot) {
			// 直接Response错误信息
			responsor.doExceptionResponse(response, "FAILED", "9999", "biz service config fail");
			return BizConsts.TYPE_ERROR_FLOW;
		}

		// 步骤6：路由到请求对应的处理类：slot,做业务处理(调用新帐务中心接口)
		// doBiz不允许向外抛异常
		BizResult bizResult = new BizResult();
		try {
			 bizResult = bizSlot.doBiz(bizParam);
		} catch (Exception e) {
			_log.error(e.toString());
			responsor.doExceptionResponse(response, "FAILED", "9999", "biz service doBiz fail");
			return BizConsts.TYPE_ERROR_FLOW;
		}

		_log.info("out response is {}",JSON.toJSONString(bizResult));

		// 步骤7：记录消息到日志表
		// startTime = bizParam.getParamLong(BizConsts.KEY_RQUEST_START_TIME);
		LogUtil.saveLogToABM_TMall(request,bizResult.getCode(), startTime);
		
		// 步骤8：响应外部
		// doResponse 不允许向外抛异常
		responsor.doResponse(bizResult, response);
		return BizConsts.TYPE_FINE_FLOW;
		
	}

}
